
//
//
//

module divider(

	clk,
    rst_n,

	load,
    numerator,
    denominator,

	quotient,
    remainder,
    ready

	);

//Bit Width Parameter
parameter  WIDTH_N      = 8;
parameter  WIDTH_D      = 4;
parameter  LOG2_WIDTH_N = 3; //log2(WIDTH_N)
localparam MIN_ND       = (WIDTH_N < WIDTH_D) ? WIDTH_N : WIDTH_D;

//Global Signals
input clk;
input rst_n;

//Operate Number
input               load;        // load the numerator and denominator
input [WIDTH_N-1:0] numerator;   // numerator
input [WIDTH_D-1:0] denominator; // enominator

//Result
output [WIDTH_N-1:0] quotient;   // quotient
output [WIDTH_D-1:0] remainder;  // remainder
output               ready;      // result is valid now

//
reg [WIDTH_N + MIN_ND:0] working;
reg [WIDTH_D - 1     :0] denom;

wire [WIDTH_N-1:0] lower_working = working [WIDTH_N-1:0];
wire [MIN_ND:0] upper_working = working [WIDTH_N + MIN_ND : WIDTH_N];

wire [WIDTH_D:0] sub_result = upper_working - denom;
wire sub_result_neg = sub_result[WIDTH_D];

reg [LOG2_WIDTH_N:0] cntr;
wire cntr_zero = ~|cntr;


always @ (posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0)
    begin
    working <= 0;
    denom <= 0;
    cntr <= 0;
    end
else
    begin
    if (load)
        begin
        working <= {{WIDTH_D{1'b0}},n,1'b0};
        cntr <= WIDTH_N;
        denom <= denominator;
        end
    else
        begin
        if (!cntr_zero)
            begin
            cntr <= cntr - 1;
            working <= sub_result_neg ? {working[WIDTH_N+MIN_ND-1:0],1'b0} :
                                        {sub_result[WIDTH_D-1:0],lower_working,1'b1};
            end
        end
    end
end

reg [WIDTH_N-1:0] quotient;
reg [WIDTH_D-1:0] remainder;
reg               ready;
always @ (posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0)
    begin
    quotient  <= {WIDTH_N{1'b0}};
    remainder <= {WIDTH_D{1'b0}};
    ready     <= 1'b0;
    end
else
    begin
    quotient  <= lower_working;
    remainder <= upper_working >> 1;
    ready     <= cntr_zero;
    end
end

endmodule
